package org.bp.struct;

import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;

import org.bp.util.ThreadUtils;

/**
 * 线程安全的队列
 */
public class ThreadSafeQueue<T> {
    private List<T> itemList = new LinkedList<T>();

    // 默认不限制大小
    private int maxSize = -1;

    public ThreadSafeQueue() {}

    public ThreadSafeQueue(int maxSize) {
        this.maxSize = maxSize;
    }

    /**
     * 加锁的push，给外部功能使用
     */
    public void securePush(T item) {
        while(maxSize > 0 && size() > maxSize) {
        	ThreadUtils.sleep(10);
        }

        synchronized (this) {
            itemList.add(item);
        }
    }

    public void securePushAll(Collection<T> itemList) {
        for (T item: itemList) {
            synchronized (this) {
                this.itemList.add(item);
            }
        }
    }

    /**
     * 不加锁的push，给内部功能使用
     */
    public synchronized void push(T item) {
        itemList.add(item);
    }

    public synchronized void pushAll(Collection<T> itemList) {
        this.itemList.addAll(itemList);
    }

    public synchronized int size() {
        return itemList.size();
    }

    public synchronized T shift() {
        if(itemList.size() > 0) {
            return itemList.remove(0);
        } else {
            return null;
        }
    }

    public synchronized List<T> shiftSeveral(int num) {
        synchronized (this) {
            num = Math.min(num, itemList.size());
            List<T> array = new ArrayList<>(num);
            for (int i = 0; i < num; ++i) {
                array.add(itemList.remove(0));
            }

            return array;
        }
    }

    public synchronized void clear() {
        itemList.clear();
    }

    public synchronized T head() {
        return itemList.get(0);
    }

    public void setMaxSize(int maxSize) {
        this.maxSize = maxSize;
    }
}
